package cz.vse.adventura.po1715.xkosd00_kostka.hra;

import cz.vse.adventura.po1715.xkosd00_kostka.hra.Hra;
import  cz.pecinovsky.english.pojj.adv_framework.game_txt.IUI;
import  cz.pecinovsky.english.pojj.adv_framework.game_txt.IGame;
import cz.vse.adventura.po1715.xkosd00_kostka.hra.Hra;

import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.IOException;



/*******************************************************************************
 * Instance třídy {@code StreamUI} představují ...
 *
 * @author    Dominik KOSTKA
 * @version   1.00.000
 */
public class StreamUI implements IUI
{
//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================

    private static final String PROLOG = "\n------------------------------\n";
    private static final String EPILOG = PROLOG + "\nZadej prikaz: ";


//== PROMĚNNÉ ATRIBUTY TŘÍDY ===================================================
//== KONSTANTNÍ ATRIBUTY INSTANCÍ ==============================================

    private final BufferedReader reader;
    private final PrintWriter    writer;


//== PROMĚNNÉ ATRIBUTY INSTANCÍ ================================================

//    private Charset inpChS = new ;
//    private Charset outChS = "UTF-8";



//== PŘÍSTUPOVÉ METODY ATRIBUTŮ TŘÍDY ==========================================
//== OSTATNÍ NESOUKROMÉ METODY TŘÍDY ===========================================

//##############################################################################
//== KONSTRUKTORY A TOVÁRNÍ METODY =============================================

    /***************************************************************************
     * Vytvoří novou instancí textového rozhraní,
     * která bude číst ze standardního vstupu a zapisovat na standardní výstup.
     */
    public StreamUI()
    {
         this(System.in, System.out);
    }


    /***************************************************************************
     * Vytvoří novou instancí textového rozhraní,
     * která bude číst ze zadaného vstupního proudu
     * a zapisovat na zadaného výstupního proudu.
     *
     * @param in  Proud, z nějž se bude číst
     * @param out Proud, do nějž se bude zapisovat
     */
    public StreamUI(InputStream in, OutputStream out)
    {
         this(new InputStreamReader(in),
              new OutputStreamWriter(out));
         System.out.println(
               "Input:  " + new InputStreamReader(in)  .getEncoding() +
             "\nOutput: " + new OutputStreamWriter(out).getEncoding());
    }


    /***************************************************************************
     * Vytvoří novou instancí textového rozhraní,
     * která bude číst ze zadaného vstupního proudu typu Reader
     * a zapisovat na zadaného výstupního proudu typu Writer.
     *
     * @param reader Proud, z nějž se bude číst
     * @param writer Proud, do nějž se bude zapisovat
     */
    public StreamUI(Reader reader, Writer writer)
    {
         this(new BufferedReader(reader), new PrintWriter(writer));
    }


    /***************************************************************************
     * Vytvoří novou instancí textového rozhraní,
     * která bude číst ze zadaného vstupního proudu typu BufferedReader
     * a zapisovat na zadaného výstupního proudu typu PrintWriter.
     *
     * @param reader Proud, z nějž se bude číst
     * @param writer Proud, do nějž se bude zapisovat
     */
    public StreamUI(BufferedReader reader, PrintWriter writer)
    {
         this.reader = reader;
         this.writer = writer;
    }



//== ABSTRAKTNÍ METODY =========================================================
//== PŘÍSTUPOVÉ METODY INSTANCÍ ================================================
//== OSTATNÍ NESOUKROMÉ  METODY INSTANCÍ =======================================

    /***************************************************************************
     * Spusti komunikaci mezi zadanou hrou a danou instanci
     * majici na starosti komunikaci s uzivatelem.
     *
     * @param hra Hra, kterou ma dane GUI spustit
     */
    @Override
    public void startGame( IGame hra )
    {
        String radek = "";
        for(;;) {
            String odpoved = hra.executeCommand(radek);
            writer.print(PROLOG + odpoved + EPILOG);
            if (writer.checkError()) {
                throw new RuntimeException("\nChyba při tisku odpovědi");
            }

            if (hra.isReady())  { break; }

            try {
                radek = reader.readLine();
            }catch(IOException ioe) {
                throw new RuntimeException("\nChyba při čtení příkazu");
            }

            if (radek == null) { break; }
        }
    }


    /***************************************************************************
     * Spusti komunikaci mezi implicitni hrou a danou instanci
     * majici na starosti komunikaci s uzivatelem.
     */
    @Override
    public void startGame()
    {
        startGame(Hra.getHra());
    }



//== SOUKROMÉ A POMOCNÉ METODY TŘÍDY ===========================================
//== SOUKROMÉ A POMOCNÉ METODY INSTANCÍ ========================================
//== VNOŘENÉ A VNITŘNÍ TŘÍDY ===================================================
//== TESTOVACÍ METODY A TŘÍDY ==================================================

    /***************************************************************************
     * Testovací metoda.
     */
//    public static void test()
//    {
//         StreamUI sui = new StreamUI();
//         sui.startGame();
//    }
//    /** @param args Parametry příkazového řádku - nepoužité. */
//    public static void main( String[] args ) { test(); }
}
